{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Jupyter IPython notebook Capable of Rendering Buffers (rasters) Used/Produced by `test_flate_png.py` tests\n",
    "\n",
    "(requires matplotlib)\n",
    "\n",
    "After running any of these tests (`pytest -k test_flate_png_alt_file`), two files are produced: `./result.pickle` and `./expected.pickle`.\n",
    "\n",
    "These files contain buffers that can be rendered. Both rendered buffers must be identical\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Boiler plate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as pyplot\n",
    "import array\n",
    "import ast\n",
    "\n",
    "def pixel(bytes, color_type):\n",
    "    if color_type == 0:\n",
    "        assert len(bytes) == 1, \"expected 1 but got %d\" % len(bytes)\n",
    "        #print bytes\n",
    "        bytes = [bytes[0]/255.0, bytes[0]/255.0, bytes[0]/255.0]\n",
    "        \n",
    "    elif color_type == 2:\n",
    "        assert len(bytes) == 3, \"expected 3 but got %d\" % len(bytes)\n",
    "        #print bytes\n",
    "        bytes = [bytes[0]/255.0, bytes[1]/255.0, bytes[2]/255.0]\n",
    "        \n",
    "    elif color_type == 'rgb':\n",
    "        assert len(bytes) == 3, \"expected 3 but got %d\" % len(bytes)\n",
    "        bytes = [(int)(bytes[0] * 255) % 256, (int)(bytes[1] * 255.0) % 256, (int)(bytes[2] * 255.0) % 256]\n",
    "        \n",
    "    else:\n",
    "        raise ValueError(\"Unsupported color_type %d\" % color_type)\n",
    "    return bytes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def rasterizer(data, rowbytes, bytes_per_pixel, color_type, filter_included=False):\n",
    "    raster = []\n",
    "    \n",
    "    first_pixel = 0\n",
    "    if filter_included:\n",
    "        rowbytes += 1\n",
    "        first_pixel = 1\n",
    "        \n",
    "    for r in xrange(0, len(data), rowbytes):\n",
    "        row = data[r : r + rowbytes]\n",
    "        #print \"row\", row, len(row)\n",
    "        raster_row = []\n",
    "\n",
    "        for c in xrange(first_pixel, rowbytes, bytes_per_pixel):\n",
    "            #print c, bytes_per_pixel, row[c : c + bytes_per_pixel]\n",
    "            p = pixel(row[c : c + bytes_per_pixel], color_type)\n",
    "            #print p\n",
    "            raster_row.append(p)\n",
    "\n",
    "        raster.append(raster_row)\n",
    "    return raster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_png_log(png_log):\n",
    "    '''\n",
    "    Lifted from test_flate_png.py :: util_test_flate_png_alt_from_png_log_file\n",
    "    \n",
    "    Reads xxxxx.png.log and produces a raster of both expected and data\n",
    "    '''\n",
    "    with open(png_log) as f:\n",
    "        \n",
    "        data = array.array('B')\n",
    "        expected = array.array('B')\n",
    "        width = 0 \n",
    "        bit_depth = 0 \n",
    "        channels = 0 \n",
    "        color_type = 0 \n",
    "        pixel_depth = 0 \n",
    "        rowbytes = 0 \n",
    "        filter = 0 \n",
    "        nrows = 0 \n",
    "\n",
    "        for l in f.readlines():\n",
    "\n",
    "            if l.startswith(\"PASS:\"):\n",
    "                break\n",
    "\n",
    "            l = l.split(' = ')\n",
    "            var = l[0]\n",
    "            val = l[1]\n",
    "\n",
    "            if var == 'width':\n",
    "                width = int(val)\n",
    "\n",
    "            elif var == 'bit_depth':\n",
    "                bit_depth = int(val)\n",
    "\n",
    "            elif var == 'channels':\n",
    "                channels = int(val)\n",
    "\n",
    "            elif var == 'color_type':\n",
    "               color_type = int(val)\n",
    "\n",
    "            elif var == 'pixel_depth':\n",
    "                pixel_depth = int(val)\n",
    "\n",
    "            elif var == 'rowbytes':\n",
    "                rowbytes = int(val)\n",
    "\n",
    "            elif var == 'filter':\n",
    "                filter = int(val)\n",
    "\n",
    "            elif var == 'data':\n",
    "                d = ast.literal_eval(val)\n",
    "                data.append(filter)\n",
    "                data.extend(d)\n",
    "\n",
    "            elif var == 'expected':\n",
    "                e = ast.literal_eval(val)\n",
    "                expected.extend(e)\n",
    "                nrows += 1\n",
    "\n",
    "        print(\"width: %d\" % width)\n",
    "        print(\"bit_depth: %d\" % bit_depth)\n",
    "        print(\"channels: %d\" % channels)\n",
    "        print(\"color_type: %d\" % color_type)\n",
    "        print(\"pixel_depth: %d\" % pixel_depth)\n",
    "        print(\"rowbytes: %d\" % rowbytes)\n",
    "        print(\"filter: %d\" % filter)\n",
    "        print(\"expected: %d\" % len(expected))\n",
    "        print(\"data: %d\" % len(data))\n",
    "        print(\"nrows: %d\" % nrows)\n",
    "\n",
    "        assert color_type in [\n",
    "                    0, # Grayscale (Y)\n",
    "                    2, # Truecolor (RGB)\n",
    "                    # 3 Indexed is not supported (Palette)\n",
    "                    4, # Grayscale with alpha (YA)\n",
    "                    6, # Truecolor with alpha (RGBA)\n",
    "                ]\n",
    "        assert filter in [0, 1, 2, 3, 4]\n",
    "        assert channels * bit_depth == pixel_depth\n",
    "        assert (pixel_depth // 8) * width == rowbytes\n",
    "        bytes_per_pixel = pixel_depth // 8\n",
    "        assert 0 == pixel_depth % 8 # can't support pixels with bit_depth < 8\n",
    "        assert 8 == bit_depth # ideally, we should test bit_depth 16 also\n",
    "        assert nrows * (1 + width * bytes_per_pixel) == len(data) # 1 filter byte preceeding each row\n",
    "        assert nrows * width * bytes_per_pixel == len(expected)\n",
    "\n",
    "        ### Rasterize each buffer\n",
    "        raster = rasterizer(expected, rowbytes, bytes_per_pixel, color_type)\n",
    "        raster2 = rasterizer(data, rowbytes, bytes_per_pixel, color_type, filter_included=True)\n",
    "        \n",
    "    return (raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizations of pre-canned xxx.png.log files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 3\n",
      "color_type: 2\n",
      "pixel_depth: 24\n",
      "rowbytes: 96\n",
      "filter: 1\n",
      "expected: 3072\n",
      "data: 3104\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1058f5bd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./basn2c08.png.log')\n",
    "    \n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 1\n",
      "color_type: 0\n",
      "pixel_depth: 8\n",
      "rowbytes: 32\n",
      "filter: 1\n",
      "expected: 1024\n",
      "data: 1056\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x107b84c90>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./basn0g08.png.log')\n",
    "\n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 3\n",
      "color_type: 2\n",
      "pixel_depth: 24\n",
      "rowbytes: 96\n",
      "filter: 1\n",
      "expected: 3072\n",
      "data: 3104\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x108000ed0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./f01n2c08.png.log')\n",
    "\n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 3\n",
      "color_type: 2\n",
      "pixel_depth: 24\n",
      "rowbytes: 96\n",
      "filter: 2\n",
      "expected: 3072\n",
      "data: 3104\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x108168a50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./f02n2c08.png.log')\n",
    "\n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 3\n",
      "color_type: 2\n",
      "pixel_depth: 24\n",
      "rowbytes: 96\n",
      "filter: 3\n",
      "expected: 3072\n",
      "data: 3104\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x106bd8ad0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./f03n2c08.png.log')\n",
    "\n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width: 32\n",
      "bit_depth: 8\n",
      "channels: 3\n",
      "color_type: 2\n",
      "pixel_depth: 24\n",
      "rowbytes: 96\n",
      "filter: 4\n",
      "expected: 3072\n",
      "data: 3104\n",
      "nrows: 32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n8osU6v8B4uPbVzqaMNQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x107b4bfd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(raster, raster2), (data, expected), (width, bit_depth, channels, color_type, pixel_depth, rowbytes, filter) \\\n",
    "    = load_png_log('./f04n2c08.png.log')\n",
    "\n",
    "pyplot.imshow(raster)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Utility code to visually compare the `result` produced by test-case and its `expected` output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "32\n",
      "32\n",
      "32\n",
      "32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n8osU6v8B4uPbVzqaMNQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x106d0c7d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3072\n",
      "32\n",
      "32\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n8osU6v8B4uPbVzqaMNQAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x105924d10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#\n",
    "# After running any of these tests (pytest -k test_flate_png_alt_file),\n",
    "#   two files are produced: tests/result.pickle and tests/expected.pickle.\n",
    "#   These files contain buffers that can be rendered\n",
    "#   Both rendered buffers must be identical\n",
    "\n",
    "import pickle\n",
    "with open('./result.pickle', 'rb') as f:\n",
    "    result = pickle.load(f)\n",
    "\n",
    "print len(raster)\n",
    "print len(raster[0])\n",
    "    \n",
    "res = rasterizer(result, 96, 3, 2)\n",
    "    \n",
    "print len(res)\n",
    "print len(res[0])\n",
    "\n",
    "pyplot.imshow(res)\n",
    "pyplot.show()\n",
    "\n",
    "with open('./expected.pickle', 'rb') as f:\n",
    "    expected = pickle.load(f)\n",
    "\n",
    "print len(expected)\n",
    "    \n",
    "res = rasterizer(expected, 96, 3, 2)\n",
    "    \n",
    "print len(res)\n",
    "print len(res[0])\n",
    "\n",
    "pyplot.imshow(res)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
